/*
 * AreaDibujo.h
 *
 *  Created on: 25/11/2009
 *      Author: luis
 */

#ifndef AREADIBUJO_H_
#define AREADIBUJO_H_

#include <gtkmm.h>
#include "VistaFondo.h"
#include "VistaCompuerta.h"
#include "VistaCables.h"
#include "../Modelo/Circuito.h"
#include "VentanaSalida.h"
#include "../Modelo/ElementoExterno.h"


class AreaDibujo: public Gtk::DrawingArea {
private:
	//Puntero a la ventana superior
	class VentanaPrincipal* ventana_superior;

	//Vistas para pintar
	VistaFondo vista_fondo;
	VistaCompuerta vista_compuerta;
	VistaCables vista_cable;

	//Enteros auxiliares para pintar compuertas
	int nro_salida, cant_entradas_caja, cant_salidas_caja, pos_x_inicial, pos_y_inicial, pos_x_aux, pos_y_aux;
	int cuadro_ocupado_x, cuadro_ocupado_y, sentido;

	//Enteros para manejar estado de area dibujo
	int estado, estado_anterior, estado_traslado;

	int nro_id;

	//Circuito actual del area
	Circuito* circuito_actual;

	//Objetos auxiliares
	ElementoCircuital* auxiliar;
	Cable* cable_auxiliar;


	/*
	 * Funciones de validacion
	 */

	/*
	 * Funcion que pregunta si la posicion es valida para dejar un elemento
	 */
	bool es_posicion_valida(int x, int y);


	/*
	 * Funcion que devuelve true si hay otro elemento en la posicion x, y ademas del elemento pasado
	 * por parametro
	 */
	bool hay_otro_elem(int x, int y, ElementoCircuital* elemento);

	bool es_conexion_valida(ElementoCircuital* elemento, int nro_entrada, int x, int y);

	/*
	 * Detecta si hay caracteres que no son alfanumericos
	 */
	bool es_nro_valido(std::string numero);

	/*
	 * Funciones de validacion para el movimiento del cable
	 */

	/*
	 * Funciones que detectan si el nro x, y esta corrido a la derecha hacia arriba, abajo o izquierda
	 * respecto del anterior punto de referencia (pos_x_inicial, pos_y_inicial)
	 */
	bool es_derecha(int x, int y);

	bool es_izquierda(int x, int y);

	bool es_abajo (int x, int y);

	bool es_arriba (int x, int y);


	/*
	 * Funciones de evento button_press
	 */

	/*
	 * Agrega un punto al trazado del cable
	 */
	void agregar_punto_cableado(GdkEventButton* event);

	void iniciar_traslacion(GdkEventButton* event);

	void rotar (int x, int y);

	void iniciar_traslacion_masiva(GdkEventButton* event);

	void borrar_compuerta(GdkEventButton* event);


	/*
	 * Funciones del evento button_release
	 */

	void crear_compuerta(GdkEventButton* event);

	void terminar_traslacion(GdkEventButton* event);

	void seleccionar (int pos_x_inicial,int pos_y_inicial,int pos_x_aux,int pos_y_aux);

	void deshacer_seleccion();


	/*
	 * Funciones del evento motion
	 */

	void repintar_movimiento_elem(GdkEventMotion* event);

	void repintar_traslacion_masiva(GdkEventMotion* event);

	void repintar_cableado(GdkEventMotion* event);

	void terminar_cableado(GdkEventButton* event);


	/*
	 * Funciones auxiliares
	 */

	void actualizar_situacion(int x, int y);

	/*
	 *	Pinta el cable trazandose llamando a una funcion de la vista cable
	 */
	void pintar_linea();

	void borrar_cable (float x, float y);

	void sel_cables_mov_extremo();


public:

	AreaDibujo(Circuito* circuito, VentanaPrincipal* ventana_superior);

	void actualizar_estado();

	void set_nro_id(int id){
		this->nro_id = id;
	}

	void nuevo_elem_externo_aux(int x, int y, int ID, std::string IP ,int port, Cliente* cliente,int cant_entrada,int cant_salida, std::string name){
		auxiliar = this->circuito_actual->nueva_elemento_externo(x, y, ID, IP,port, cliente, cant_entrada, cant_salida, name);

	}

	int get_id(){
		return this->nro_id;
	}
	void pintar_estado_actual();

	void set_estado(int estado);

	virtual ~AreaDibujo();

	Circuito* get_circuito_actual(){return this->circuito_actual;}

	int get_estado_anterior(){
		return this->estado_anterior;
	}

	void borrar_seleccion();

	void simular();

	void pintar_en_contexto(Cairo::RefPtr<Cairo::Context> cr, float x, float y);

protected:

	/*
	 * Eventos que capta el area
	 */
	virtual bool on_expose_event(GdkEventExpose* event);
	virtual bool on_eventbox_button_press(GdkEventButton* event);
	virtual bool on_eventbox_button_release(GdkEventButton * event);
	virtual bool on_eventbox_motion_event(GdkEventMotion *event);

};

#endif /* AREADIBUJO_H_ */
